Lattice Crosslink Bring up and Testing

From RidgeRun Developer Wiki

Follow Us On Twitter LinkedIn Email Share this page






Preferred Partner Logo 3 NXP Partner Program





This section describes the detailed hardware and software requirements needed to build, program, and validate the Lattice CrossLink camera emulator.

Hardware requirements

The camera emulator is implemented using a Lattice CrossLink Master Link Board, which provides native MIPI D-PHY support required for CSI-2 transmission.

The complete hardware setup includes:

  • Lattice CrossLink Master Link Evaluation Board (LIF-MD6000) [3]
  • NVIDIA Jetson Xavier Developer Kit
  • Custom FP15–FX12 adapter board used to interface the FPGA with the Jetson CSI connector
  • 15-pin FFC/FPC CSI camera cable
Top view of the Lattice CrossLink FPGA evaluation board [1].
NVIDIA Jetson Xavier NX Developer Kit [2].
Front and back views of the custom connector adapter board.


You can find the schematic and BOM for the FP15-FX12 connector board in the following reference. See Getting the Code

Software requirements

The following software components are required to build, program, and validate the camera emulator:

  • Lattice Diamond FPGA development environment: Used to synthesize, implement, and program the CrossLink FPGA design.
  • JetPack SDK for NVIDIA Jetson platforms: Provides the Linux kernel, camera drivers, and user-space camera stack. Recommended for this project: Jetpack 5.x or 6.x
  • GStreamer: Used to capture, visualize, and record video streams from the emulated camera. Already installed with Jetpack.
  • v4l2-utils: Useful for inspecting camera nodes and validating device detection. Install with sudo apt install v4l-utils

Project structure

Project Source Files:

  • csi2_tx_simulator_ctrl.v: Implements the main control logic for the CSI-2 transmitter, including frame sequencing, line timing, and synchronization signals.
  • filter.v: Contains optional filtering logic used during test pattern or image data generation.
  • i2cslave_controller.v: Implements the core logic of the I²C slave interface used to emulate sensor register access.
  • i2cslave_controller_top.v: Top-level wrapper for the I²C slave module, integrating the controller with the internal register file.
  • i2c_user_regfiler_addr16.v: Defines the 16-bit addressable register map exposed through the I²C interface, emulating the IMX219 sensor register behavior.
  • image_generator.v: Generates RAW10 image data according to the selected sensor mode, resolution, and frame timing parameters.
  • simulator_top.v: Top-level module integrating the CSI-2 transmitter IP, image generator, and I²C slave interface into a complete camera emulator design.
  • camera_emulator_constraints.lpf: Project-specific constraint file defining pin assignments and timing constraints for the CrossLink FPGA used in this camera emulator design.

Project Testbench Files:

  • i2c_master.v: Testbench I²C master used to simulate register transactions with the I²C slave during verification.
  • tb_defines.v: Contains common definitions, constants, and parameters shared across the testbench files.

Bring up

Building the FPGA Project

To begin, you need to have the Diamond software installed. For installation instructions, downloads, and licensing information, refer to the official Lattice Diamond “Getting Started” page [4].

For a general overview of the Diamond design environment, Lattice also provides a detailed introduction on their page [5].

For a quick introduction to the Diamond environment, the following video provides an excellent overview [6].

Once installed and licensed, Diamond can be launched directly from the terminal. On Linux, you can start the GUI by running:

diamond &

If the command is not recognized, you can also launch it using the full installation path:

<install_path>/diamond/3.14/bin/lin64/diamond &

Once Diamond is open, start by creating a new project. You will be asked to specify a project name and a directory where the project will be stored. Feel free to save it in any location you prefer. Next, add the project’s source files, including both the HDL files (except for the i2c_master.v) and the LPF constraint file.

The following step requires selecting the target FPGA device. This project was developed using the Lattice CrossLink LIF-MD6000, so make sure to select this device as shown in the image below. If you are working with a different FPGA or board revision, simply adjust the device selection to match your specific hardware.

Lattice Diamond device selection window configured for the CrossLink LIF-MD6000 FPGA.


Finally, choose the synthesis tool. This project uses the default “Lattice LSE,” so no changes are required to finish the project configuration.

Creating IP Core

The next step to recreate the camera emulator is to generate the IP core used in this design. Diamond includes Clarity Designer, an integrated tool used to generate and configure IP cores. More detailed guidance on its features and workflow is available in the Clarity Designer User Manual.

Start by opening Clarity Designer. It can be accessed from the Tools menu or by clicking the Clarity icon in the toolbar. Next, create a new Clarity design and name it “csi2_output.”

Once the design has been created, Clarity Designer will open in the main interface. From here, switch to the Lattice IP Server tab and select the entry labeled “IP (Click to get IP information)” to access the available IP modules.

With the IP catalog loaded, select the CSI-2/DSI D-PHY Transmitter (version 1.3) and use the Install option at the top of the interface. When prompted, choose any directory where you want the IP files to be saved.

CSI-2/DSI D-PHY Transmitter IP overview displayed in Clarity Designer.

Once the IP has been installed, switch to the Lattice IP tab. The newly added CSI-2/DSI D-PHY Transmitter will appear in the list of available IP cores. Select it to open the configuration window.

CSI-2/DSI D-PHY Transmitter IP listed in the Clarity Designer catalog.


When selected, Clarity Designer will first prompt for an instance name. For this project, the instance is named "csi2_raw10_output", as it will identify the generated module within the design hierarchy. Next, proceed to configure the IP parameters. The image below shows the configuration adopted for this design.

CSI-2/DSI D-PHY Transmitter IP configuration interface in Clarity Designer.


After applying the configuration, Clarity Designer displays a log window. A successful configuration is indicated by a log with zero errors and zero warnings, confirming that the IP parameters have been applied correctly.

Finally, generate the IP by selecting the Generate option at the top of the Clarity Designer window. Once the generation completes, the file csi2_output.sbx will appear in the project’s source files, indicating that the IP has been successfully created.

Programming FPGA

Before programming the FPGA, the bitstream file must be generated by running the complete implementation flow in Diamond. This is done from the Process pane by executing all steps up to Export Files, as shown in the figure below.

Complete implementation flow displayed in the Diamond design environment.

Before opening the Programmer tool, ensure that the CrossLink board is properly connected and powered on. If the board or programming cable is not connected, Diamond may fail to detect the JTAG chain and report driver or cable-related warnings in the output console.

If you experience minute-long waits, please disconnect non-essential USB hubs or devices
If you are on Ubuntu 24.04, use the programmer executable (<install_path>/diamond/3.14/bin/lin64/programmer}) with sudo

The FPGA is programmed using Diamond’s Programmer tool, which can be accessed from the Tools menu or from the toolbar. After opening the Programmer, the first step is to verify that the programming cable is correctly detected. This is configured from the Cable Settings panel, where the cable detection and default programming settings are shown.

Device programming process displayed in the Diamond Programmer tool.

Once the cable is detected, the connected device is displayed in the Programmer device table. The device family and part number must match the Lattice CrossLink LIF-MD6000 used in this project. At this stage, the generated bitstream file is also loaded into the programming table.

If the cable is not detected, a known issue is the presence of the ftdi_sio driver, which can be fixed by:

sudo rmmod ftdi_sio 
sudo rmmod usbserial

Once the cable is detected, the connected device is displayed in the Programmer device table. The device family and part number must match the Lattice CrossLink LIF-MD6000 used in this project. At this stage, the generated bitstream file is also loaded into the programming table.

With the device and bitstream correctly recognized, the programming operation can be initiated by pressing the Program button. A successful programming process completes without errors and leaves the FPGA ready for use.

Testing video capture

Once the FPGA has been successfully programmed, you can proceed to power on the Jetson.

It is important that the CrossLink board is already connected and programmed before the Jetson boots, as the device must be detected as a camera interface during startup. If the board is not ready during boot, the kernel will not initialize the CSI camera nodes, and the device will not appear under /dev/video*.

Before running any capture pipeline, it is useful to confirm that the Jetson has correctly detected the emulated IMX219 sensor during boot. This can be checked in the Linux terminal using:

sudo dmesg | grep imx219

A successful initialization will show log messages indicating that the tegra-camera driver has bound the IMX219 node to the correct I²C address (typically 9-0010). If the CrossLink board was not programmed at boot time, the log may instead report I²C read errors or a failed probe.

Once detection is confirmed, you can proceed to test video capture using GStreamer. The following pipelines demonstrate how to record video for two of the supported sensor modes.

For mode 0:

gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM), width=3280, height=2464, format=(string)NV12, framerate=(fraction)20/1' ! nvvidconv ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location=test.mp4 -e

For mode 2:

gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM), width=1920, height=1080, format=(string)NV12, framerate=(fraction)30/1' ! nvvidconv ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location=test.mp4 -e

After recording, the resulting video files can be played back using:

gst-play-1.0 test.mp4

Bring-up Validation

Successful video capture shows that Argus is able to enumerate the available sensor modes, confirming that the emulated IMX219 sensor was detected correctly:

 GST_ARGUS: Available Sensor modes :
 GST_ARGUS: 3280 x 2464 FR = 21.000000 fps
 GST_ARGUS: 3280 x 1848 FR = 28.000001 fps
 GST_ARGUS: 1920 x 1080 FR = 29.999999 fps
 GST_ARGUS: 1640 x 1232 FR = 29.999999 fps
 GST_ARGUS: 1280 x 720 FR = 59.999999 fps

A successful execution completes with the following message:

 GST_ARGUS: Done Success

While running the GStreamer capture pipelines, kernel messages can be monitored in real time using:

 dmesg -w

When the capture pipeline runs successfully, no camera-related kernel messages are produced. Errors only appear when the system enters a faulty capture state.

Known issues

In some situations, the capture pipeline fails and cannot recover automatically. At the GStreamer level, this is observed with the following errors:

nvbuf_utils: dmabuf_fd -1 mapped entry NOT found
NvBufSurfaceFromFd Failed
Error generated (propagating)

At the same time, monitoring the kernel log shows camera and VI-related errors such as:

tegra-camrtc-capture-vi: uncorr_err: request timed out after 2500 ms
vi_capture_control_message: NULL VI channel received
csis_stream_open: VI channel not found
[RCE] ERROR: camera-ip capture scheduler

These messages indicate that the CSI/VI capture stack has entered an unrecoverable state. Once this condition occurs, restarting the capture pipeline is not sufficient and a full reboot of the Jetson is required to restore normal operation:

sudo reboot

Also, v4l2-ctl is usually unable to capture buffers. It is only possible through Argus